package com.cj.sys.service.security;

import java.util.List;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cj.common.orm.hibernate.EntityManager;
import com.cj.common.orm.hibernate.HibernateDao;
import com.cj.common.utils.TreeUtil;
import com.cj.sys.dao.security.DeptDao;
import com.cj.sys.dao.security.UserDao;
import com.cj.sys.entity.security.Dept;
import com.cj.sys.entity.security.User;
import com.cj.sys.service.ServiceException;
@Service
@Transactional
public class DeptManager extends EntityManager<Dept, Long>{
	@Autowired
	DeptDao deptDao;
	@Autowired
	UserDao userDao;

	@Override
	public void save(Dept entity) throws ServiceException {
		String oldFullName = this.load(entity.getId()).getFullName();
		super.save(entity);
		if(!oldFullName.equals(entity.getFullName())){
			List<User> users = userDao.findByDeptId(entity.getId());
			for(User user:users){
				userDao.save(user);
			}
			Set<Dept> depts = entity.getChildren();
			for(Dept dept : depts){
				this.save(dept);
			}
		}
	}
	
	private String allDeptsXml;
	@Transactional(readOnly = true)
	public String createDeptsXml(Long rootId,Long exceptionId){
//		if(allDeptsXml == null){
//			synchronized (this) {
//				if(allDeptsXml == null){
					try {
						Document doc = DocumentHelper.createDocument();
						doc.setXMLEncoding("UTF-8");
						Element root = doc.addElement("TreeNode");
						List<Dept> allDepts = deptDao.getAll();
						if(exceptionId != null)
							allDepts.remove(this.load(exceptionId));
						getXMLElement(root,allDepts,rootId);
						return doc.asXML();
					} catch (Exception e) {
						logger.error(e.getMessage(), e);
						throw new ServiceException(
								"getMenuXmlTree Error!" + e.getMessage(), e);
					}
//				}
//			}
//		}
//		return allDeptsXml;
	}
	
	@Transactional(readOnly = true)
	private void getXMLElement(Element root,List<Dept> depts,Long parentId){
		if(parentId == null){
			parentId = 1L;
		}
		int i = 0;
		while(!depts.isEmpty() && i < depts.size()){
			Dept dept = depts.get(i++);
			if(dept.getParent() == null){
				depts.remove(dept);
				continue;
			}
			if(parentId.equals(dept.getParent().getId()) && !parentId.equals(dept.getId())){
				Element element = TreeUtil.getElement(root, dept, "name", "id");
				depts.remove(dept);
				i=0;
				getXMLElement(element, depts, dept.getId());
			}
		}
	}	
	
	@Override
	protected HibernateDao<Dept, Long> getEntityDao() {
		return deptDao;
	}
	
	@Override
	protected  void afterChange(Dept dept) {
		allDeptsXml = null;
	}
}
